package sg.edu.nus.iss;

import java.util.*;
import java.text.*;
import org.jgap.*;

/**
 * 
 * @author Xu Guoneng
 *
 */
public class FitnessResult {

	private int evolutionIndex;
	private double bestFitness;
	private double avgFitness;
	
	private int[] bestSolution;

	public FitnessResult(int evolutionIndex, Genotype genotype){
		this.evolutionIndex = evolutionIndex;
		
		IChromosome fittest = genotype.getFittestChromosome();
		bestFitness = fittest.getFitnessValue();
		Gene[] genes = fittest.getGenes();
		bestSolution = new int[genes.length];
		for(int g = 0; g < genes.length; g++){
			bestSolution[g] = (Integer)genes[g].getAllele();
		}
		
		List<IChromosome> list = genotype.getPopulation().getChromosomes();
		if(list.size() > 0){
			double sum_fitness = 0;
			for(IChromosome item : list){
				sum_fitness += item.getFitnessValue();
			}
			avgFitness = sum_fitness / list.size();
		}
	}
	
	public double getAvgFitness() {
		return avgFitness;
	}
	
	public void setAvgFitness(double avgFitness) {
		this.avgFitness = avgFitness;
	}
	
	public double getBestFitness() {
		return bestFitness;
	}
	
	public void setBestFitness(double bestFitness) {
		this.bestFitness = bestFitness;
	}
	
	public int getEvolutionIndex() {
		return evolutionIndex;
	}
	
	public void setEvolutionIndex(int evolutionIndex) {
		this.evolutionIndex = evolutionIndex;
	}

	public String toString(){
		return "The best fitness value for round " + getEvolutionIndex() + 
				" is " + new DecimalFormat("#.##").format(bestFitness) + 
				" and average is " + new DecimalFormat("#.##").format(avgFitness);
	}
	
	public String toDetails(Package[] packages){
		String details = "";
		for(int s=0; s<Main.STACK_NUM; s++){
			
			double sum_weight = 0;
			ArrayList<Package> list = new ArrayList<Package>();
			for(int c=0; c<Main.STACK_CAPACITY; c++){
				int pid = bestSolution[s * Main.STACK_CAPACITY + c];
				list.add(packages[pid]);
				
				sum_weight += packages[pid].getWeight();
			}
			
			Collections.sort(list);
			details += "\nStack " + s + ":    (total weight = " + sum_weight + ")\n";
			for(Package p : list){
				details += p + "\n";
			}
		}
		
		return details;
	}
}
